import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_bilibili/core/extension/int_extension.dart';
import 'dart:math' as math;
import '../../../../core/model/big_data_model.dart';
import '../../../../core/model/popular_series_one_model.dart';
import '../../../../core/service/request/popular_series_one_request.dart';
import '../../../../core/service/utils/json_parse.dart';
import '../../../shared/app_theme.dart';
import '../util_chart/app_utils.dart';
import '../util_chart/legend_widget.dart';

class TempData {
  double y1;
  double y2;

  TempData(this.y1, this.y2);
}

class HYBarChartSamples extends StatefulWidget {
  const HYBarChartSamples({Key? key}) : super(key: key);

  @override
  State<HYBarChartSamples> createState() => _HYBarChartSamplesState();
}

class _HYBarChartSamplesState extends State<HYBarChartSamples> {
  List<BarChartGroupData> _showingBarGroups = [];

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Theme.of(context).canvasColor,
      child: ListView(
        children: [
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 20,
              right: 20,
            ),
            child: BuildBarCharSample01(showingBarGroups: _showingBarGroups),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 20,
              right: 20,
            ),
            child: BuildBarChartSample02(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 20,
              right: 20,
            ),
            child: BuildBarChartSample03(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 20,
              right: 20,
            ),
            child: BuildBarChartSample04(),
          ),
        ],
      ),
    );
  }
}

class BuildBarCharSample01 extends StatefulWidget {
  const BuildBarCharSample01({
    Key? key,
    required this.showingBarGroups,
  }) : super(key: key);

  final List<BarChartGroupData> showingBarGroups;

  @override
  State<BuildBarCharSample01> createState() => _BuildBarCharSample01State();
}

class _BuildBarCharSample01State extends State<BuildBarCharSample01> {
  final Color leftBarColor = const Color(0xff53fdd7);
  final Color rightBarColor = const Color(0xffff5182);
  final double width = 4;
  final _barsGradient = const LinearGradient(
    colors: [
      Colors.lightBlueAccent,
      Colors.greenAccent,
    ],
    begin: Alignment.bottomCenter,
    end: Alignment.topCenter,
  );

  BarChartGroupData makeGroupData(int x, double y1, double y2) {
    return BarChartGroupData(
      barsSpace: 10,
      x: x,
      barRods: [
        BarChartRodData(
          toY: y1,
          // color: leftBarColor,
          width: width,
          gradient: _barsGradient,
        ),
        BarChartRodData(
          toY: y2,
          color: rightBarColor,
          width: width,
          // gradient: _barsGradient,
        ),
      ],
      // showingTooltipIndicators: [0],
    );
  }

  @override
  void initState() {
    HYJsonParse.getBigData().then((value) {
      setState(() {
        List<Range> _followerAreaRange = value.fansRange.followerAreaRange;
        List<TempData> _tempDataList = [];
        for (int i = 0; i < 12; i++) {
          _tempDataList.add(TempData(0, 0));
        }
        for (var item in _followerAreaRange) {
          double _temp = double.parse(item.percent.substring(0, 4));
          switch (item.key) {
            case "-(>50%)":
              _tempDataList[0].y1 = _temp;
              break;
            case ">50%":
              _tempDataList[0].y2 = _temp;
              break;
            case "-(40-50%)":
              _tempDataList[1].y1 = _temp;
              break;
            case "40-50%":
              _tempDataList[1].y2 = _temp;
              break;
            case "-(30-40%)":
              _tempDataList[2].y1 = _temp;
              break;
            case "30-40%":
              _tempDataList[2].y2 = _temp;
              break;
            case "-(25-30%)":
              _tempDataList[3].y1 = _temp;
              break;
            case "25-30%":
              _tempDataList[3].y2 = _temp;
              break;
            case "-(20-25%)":
              _tempDataList[4].y1 = _temp;
              break;
            case "20-25%":
              _tempDataList[4].y2 = _temp;
              break;
            case "-(15-20%)":
              _tempDataList[5].y1 = _temp;
              break;
            case "15-20%":
              _tempDataList[5].y2 = _temp;
              break;
            case "-(10-15%)":
              _tempDataList[6].y1 = _temp;
              break;
            case "10-15%":
              _tempDataList[6].y2 = _temp;
              break;
            case "-(5-10%)":
              _tempDataList[7].y1 = _temp;
              break;
            case "5-10%":
              _tempDataList[7].y2 = _temp;
              break;
            case "-(3-5%)":
              _tempDataList[8].y1 = _temp;
              break;
            case "3-5%":
              _tempDataList[8].y2 = _temp;
              break;
            case "-(1-3%)":
              _tempDataList[9].y1 = _temp;
              break;
            case "1-3%":
              _tempDataList[9].y2 = _temp;
              break;
            case "-(0-1%)":
              _tempDataList[10].y1 = _temp;
              break;
            case "0-1%":
              _tempDataList[10].y2 = _temp;
              break;
            default:
              _tempDataList[11].y1 = 0;
              _tempDataList[11].y2 = 0;
          }
        }
        for (int i = 0; i < _tempDataList.length; i++) {
          final barGroup =
              makeGroupData(i, _tempDataList[i].y1, _tempDataList[i].y2);
          widget.showingBarGroups.add(barGroup);
        }
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '涨粉幅度分布',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '柱状图 (1)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildBarChart01(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildBarChart01() {
    return widget.showingBarGroups.isNotEmpty
        ? BarChart(
            BarChartData(
              maxY: 50,
              minY: 0,
              gridData: FlGridData(show: false),
              borderData: FlBorderData(show: false),
              titlesData: FlTitlesData(
                show: true,
                rightTitles:
                    AxisTitles(sideTitles: SideTitles(showTitles: false)),
                topTitles:
                    AxisTitles(sideTitles: SideTitles(showTitles: false)),
                bottomTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    getTitlesWidget: (double value, TitleMeta meta) {
                      const style = TextStyle(
                        color: Color(0xff7589a2),
                        fontWeight: FontWeight.bold,
                        fontSize: 10,
                      );
                      Widget text;
                      switch (value.toInt()) {
                        case 0:
                          text = const Text(
                            '>50%',
                            style: style,
                          );
                          break;
                        case 2:
                          text = const Text(
                            '30-40%',
                            style: style,
                          );
                          break;
                        case 4:
                          text = const Text(
                            '20-25%',
                            style: style,
                          );
                          break;
                        case 6:
                          text = const Text(
                            '10-15%',
                            style: style,
                          );
                          break;
                        case 8:
                          text = const Text(
                            '3-5%',
                            style: style,
                          );
                          break;
                        case 10:
                          text = const Text(
                            '0-1%',
                            style: style,
                          );
                          break;
                        default:
                          text = const Text(
                            '',
                            style: style,
                          );
                          break;
                      }
                      return SideTitleWidget(
                        axisSide: meta.axisSide,
                        space: 10,
                        child: text,
                      );
                    },
                    reservedSize: 30,
                  ),
                ),
                leftTitles: AxisTitles(
                  sideTitles: SideTitles(
                      showTitles: true,
                      reservedSize: 40,
                      interval: 1,
                      getTitlesWidget: (double value, TitleMeta meta) {
                        const style = TextStyle(
                          color: Color(0xff7589a2),
                          fontWeight: FontWeight.bold,
                          fontSize: 10,
                        );
                        String text;
                        if (value == 0) {
                          text = '0';
                        } else if (value == 10) {
                          text = '10';
                        } else if (value == 20) {
                          text = '20';
                        } else if (value == 30) {
                          text = '30';
                        } else if (value == 40) {
                          text = '40';
                        } else if (value == 50) {
                          text = '50';
                        } else {
                          return Container();
                        }
                        return SideTitleWidget(
                          axisSide: meta.axisSide,
                          space: 15,
                          child: Text(text, style: style),
                        );
                      }),
                ),
              ),
              barGroups: widget.showingBarGroups,
            ),
          )
        : Container();
  }
}

class BuildBarChartSample02 extends StatefulWidget {
  const BuildBarChartSample02({Key? key}) : super(key: key);

  @override
  State<BuildBarChartSample02> createState() => _BuildBarChartSample02State();
}

class _BuildBarChartSample02State extends State<BuildBarChartSample02> {
  final Color dark = const Color(0xff3b8c75);
  final Color normal = const Color(0xff64caad);
  final Color light = const Color(0xff73e8c9);
  List<Range> followerRange = [];

  @override
  void initState() {
    HYJsonParse.getBigData().then((value) {
      setState(() {
        followerRange = value.lastMonthFollower.followerRange;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日涨粉及掉粉UP主占比趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '柱状图 (2)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 16.px,
            ),
            LegendsListWidget(
              legends: [
                Legend("掉粉", dark),
                Legend("不变", normal),
                Legend("涨粉", light),
              ],
            ),
            SizedBox(
              height: 16.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildBarChart02(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildBarChart02() {
    return followerRange.isNotEmpty
        ? BarChart(BarChartData(
            alignment: BarChartAlignment.center,
            barTouchData: BarTouchData(
              enabled: false,
            ),
            titlesData: FlTitlesData(
              show: true,
              bottomTitles: AxisTitles(
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 28,
                  getTitlesWidget: bottomTitles,
                ),
              ),
              leftTitles: AxisTitles(
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 40,
                  getTitlesWidget: leftTitles,
                ),
              ),
              topTitles: AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
              rightTitles: AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
            ),
            gridData: FlGridData(
              show: true,
              checkToShowHorizontalLine: (value) => value % 10 == 0,
              getDrawingHorizontalLine: (value) => FlLine(
                color: const Color(0xffe7e8ec),
                strokeWidth: 1,
              ),
              drawVerticalLine: false,
            ),
            borderData: FlBorderData(
              show: false,
            ),
            groupsSpace: 4,
            barGroups: getData()))
        : Container();
  }

  List<BarChartGroupData> getData() {
    List<BarChartGroupData> barChartGroupDataList = [];
    List<BarChartRodStackItem> rodStackItems = [];
    double percent;
    double lastPercent = 0;
    for (int i = 0; i < followerRange.length; i++) {
      percent = double.parse(followerRange[i].percent.substring(0, 5));
      if (i % 3 == 0) {
        lastPercent = 0;
        rodStackItems.add(BarChartRodStackItem(0, percent, dark));
      } else if (i % 3 == 1) {
        rodStackItems.add(
            BarChartRodStackItem(lastPercent, percent + lastPercent, normal));
      } else {
        rodStackItems.add(BarChartRodStackItem(lastPercent, 100, light));
        barChartGroupDataList.add(BarChartGroupData(
          x: i,
          barsSpace: 2,
          barRods: [
            BarChartRodData(
                width: 5,
                toY: 100,
                rodStackItems: rodStackItems,
                borderRadius: const BorderRadius.all(Radius.zero)),
          ],
        ));
      }
      lastPercent += percent;
    }
    return barChartGroupDataList;
  }

  Widget bottomTitles(double value, TitleMeta meta) {
    const style = TextStyle(color: Color(0xff939393), fontSize: 10);
    String text;
    DateTime? date = followerRange[value.toInt()].date;
    text = "${date?.month}/${date?.day}";
    return SideTitleWidget(
      child: Text(value % 5 == 0 ? text : "", style: style),
      axisSide: meta.axisSide,
    );
  }

  Widget leftTitles(double value, TitleMeta meta) {
    if (value == meta.max) {
      return Container();
    }
    const style = TextStyle(
      color: Color(
        0xff939393,
      ),
      fontSize: 10,
    );
    return SideTitleWidget(
      child: Text(
        meta.formattedValue,
        style: style,
      ),
      axisSide: meta.axisSide,
    );
  }
}

class BuildBarChartSample03 extends StatefulWidget {
  const BuildBarChartSample03({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => BuildBarChartSample03State();
}

class BuildBarChartSample03State extends State<BuildBarChartSample03> {
  static const double barWidth = 22;
  static const shadowOpacity = 0.2;
  static const mainItems = <int, List<double>>{
    0: [2, 3, 2.5, 8],
    1: [-1.8, -2.7, -3, -6.5],
    2: [1.5, 2, 3.5, 6],
    3: [1.5, 1.5, 4, 6.5],
    4: [-2, -2, -5, -9],
    5: [-1.2, -1.5, -4.3, -10],
    6: [1.2, 4.8, 5, 5],
  };
  int touchedIndex = -1;

  @override
  void initState() {
    super.initState();
  }

  Widget bottomTitles(double value, TitleMeta meta) {
    const style = TextStyle(color: Colors.white, fontSize: 10);
    String text;
    switch (value.toInt()) {
      case 0:
        text = 'Mon';
        break;
      case 1:
        text = 'Tue';
        break;
      case 2:
        text = 'Wed';
        break;
      case 3:
        text = 'Thu';
        break;
      case 4:
        text = 'Fri';
        break;
      case 5:
        text = 'Sat';
        break;
      case 6:
        text = 'Sun';
        break;
      default:
        text = '';
        break;
    }
    return SideTitleWidget(
      child: Text(text, style: style),
      axisSide: meta.axisSide,
    );
  }

  Widget topTitles(double value, TitleMeta meta) {
    const style = TextStyle(color: Colors.white, fontSize: 10);
    String text;
    switch (value.toInt()) {
      case 0:
        text = 'Mon';
        break;
      case 1:
        text = 'Tue';
        break;
      case 2:
        text = 'Wed';
        break;
      case 3:
        text = 'Thu';
        break;
      case 4:
        text = 'Fri';
        break;
      case 5:
        text = 'Sat';
        break;
      case 6:
        text = 'Sun';
        break;
      default:
        return Container();
    }
    return SideTitleWidget(
      child: Text(text, style: style),
      axisSide: meta.axisSide,
    );
  }

  Widget leftTitles(double value, TitleMeta meta) {
    const style = TextStyle(color: Colors.white, fontSize: 10);
    String text;
    if (value == 0) {
      text = '0';
    } else {
      text = '${value.toInt()}0k';
    }
    return SideTitleWidget(
      angle: AppUtils().degreeToRadian(value < 0 ? -45 : 45),
      axisSide: meta.axisSide,
      space: 4.0,
      child: Text(
        text,
        style: style,
        textAlign: TextAlign.center,
      ),
    );
  }

  Widget rightTitles(double value, TitleMeta meta) {
    const style = TextStyle(color: Colors.white, fontSize: 10);
    String text;
    if (value == 0) {
      text = '0';
    } else {
      text = '${value.toInt()}0k';
    }
    return SideTitleWidget(
      angle: AppUtils().degreeToRadian(90),
      axisSide: meta.axisSide,
      space: 0,
      child: Text(
        text,
        style: style,
        textAlign: TextAlign.center,
      ),
    );
  }

  BarChartGroupData generateGroup(
    int x,
    double value1,
    double value2,
    double value3,
    double value4,
  ) {
    bool isTop = value1 > 0;
    final sum = value1 + value2 + value3 + value4;
    final isTouched = touchedIndex == x;
    return BarChartGroupData(
      x: x,
      groupVertically: true,
      showingTooltipIndicators: isTouched ? [0] : [],
      barRods: [
        BarChartRodData(
          toY: sum,
          width: barWidth,
          borderRadius: isTop
              ? const BorderRadius.only(
                  topLeft: Radius.circular(6),
                  topRight: Radius.circular(6),
                )
              : const BorderRadius.only(
                  bottomLeft: Radius.circular(6),
                  bottomRight: Radius.circular(6),
                ),
          rodStackItems: [
            BarChartRodStackItem(
              0,
              value1,
              const Color(0xff2bdb90),
              BorderSide(
                color: Colors.white,
                width: isTouched ? 2 : 0,
              ),
            ),
            BarChartRodStackItem(
              value1,
              value1 + value2,
              const Color(0xffffdd80),
              BorderSide(
                color: Colors.white,
                width: isTouched ? 2 : 0,
              ),
            ),
            BarChartRodStackItem(
              value1 + value2,
              value1 + value2 + value3,
              const Color(0xffff4d94),
              BorderSide(
                color: Colors.white,
                width: isTouched ? 2 : 0,
              ),
            ),
            BarChartRodStackItem(
              value1 + value2 + value3,
              value1 + value2 + value3 + value4,
              const Color(0xff19bfff),
              BorderSide(
                color: Colors.white,
                width: isTouched ? 2 : 0,
              ),
            ),
          ],
        ),
        BarChartRodData(
          toY: -sum,
          width: barWidth,
          color: Colors.transparent,
          borderRadius: isTop
              ? const BorderRadius.only(
                  bottomLeft: Radius.circular(6),
                  bottomRight: Radius.circular(6),
                )
              : const BorderRadius.only(
                  topLeft: Radius.circular(6),
                  topRight: Radius.circular(6),
                ),
          rodStackItems: [
            BarChartRodStackItem(
                0,
                -value1,
                const Color(0xff2bdb90)
                    .withOpacity(isTouched ? shadowOpacity * 2 : shadowOpacity),
                const BorderSide(color: Colors.transparent)),
            BarChartRodStackItem(
                -value1,
                -(value1 + value2),
                const Color(0xffffdd80)
                    .withOpacity(isTouched ? shadowOpacity * 2 : shadowOpacity),
                const BorderSide(color: Colors.transparent)),
            BarChartRodStackItem(
                -(value1 + value2),
                -(value1 + value2 + value3),
                const Color(0xffff4d94)
                    .withOpacity(isTouched ? shadowOpacity * 2 : shadowOpacity),
                const BorderSide(color: Colors.transparent)),
            BarChartRodStackItem(
                -(value1 + value2 + value3),
                -(value1 + value2 + value3 + value4),
                const Color(0xff19bfff)
                    .withOpacity(isTouched ? shadowOpacity * 2 : shadowOpacity),
                const BorderSide(color: Colors.transparent)),
          ],
        ),
      ],
    );
  }

  bool isShadowBar(int rodIndex) => rodIndex == 1;

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 0.8,
      child: Card(
        elevation: 4,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
        color: const Color(0xff020227),
        child: Padding(
          padding: const EdgeInsets.only(top: 16.0),
          child: BarChart(
            BarChartData(
              alignment: BarChartAlignment.center,
              maxY: 20,
              minY: -20,
              groupsSpace: 12,
              barTouchData: BarTouchData(
                handleBuiltInTouches: false,
                touchCallback: (FlTouchEvent event, barTouchResponse) {
                  if (!event.isInterestedForInteractions ||
                      barTouchResponse == null ||
                      barTouchResponse.spot == null) {
                    setState(() {
                      touchedIndex = -1;
                    });
                    return;
                  }
                  final rodIndex = barTouchResponse.spot!.touchedRodDataIndex;
                  if (isShadowBar(rodIndex)) {
                    setState(() {
                      touchedIndex = -1;
                    });
                    return;
                  }
                  setState(() {
                    touchedIndex = barTouchResponse.spot!.touchedBarGroupIndex;
                  });
                },
              ),
              titlesData: FlTitlesData(
                show: true,
                topTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    reservedSize: 32,
                    getTitlesWidget: topTitles,
                  ),
                ),
                bottomTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    reservedSize: 32,
                    getTitlesWidget: bottomTitles,
                  ),
                ),
                leftTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    getTitlesWidget: leftTitles,
                    interval: 5,
                    reservedSize: 42,
                  ),
                ),
                rightTitles: AxisTitles(
                  sideTitles: SideTitles(
                    showTitles: true,
                    getTitlesWidget: rightTitles,
                    interval: 5,
                    reservedSize: 42,
                  ),
                ),
              ),
              gridData: FlGridData(
                show: true,
                checkToShowHorizontalLine: (value) => value % 5 == 0,
                getDrawingHorizontalLine: (value) {
                  if (value == 0) {
                    return FlLine(
                        color: const Color(0xff363753), strokeWidth: 3);
                  }
                  return FlLine(
                    color: const Color(0xff2a2747),
                    strokeWidth: 0.8,
                  );
                },
              ),
              borderData: FlBorderData(
                show: false,
              ),
              barGroups: mainItems.entries
                  .map((e) => generateGroup(
                      e.key, e.value[0], e.value[1], e.value[2], e.value[3]))
                  .toList(),
            ),
          ),
        ),
      ),
    );
  }
}

class BuildBarChartSample04 extends StatefulWidget {
  const BuildBarChartSample04({Key? key}) : super(key: key);

  @override
  State<BuildBarChartSample04> createState() => _BuildBarChartSample04State();
}

class _BuildBarChartSample04State extends State<BuildBarChartSample04> {
  List<ListElement> _list = [];
  int touchedGroupIndex = -1;

  BarChartGroupData generateBarGroup(
    int x,
    double share,
    double like,
    double coin,
  ) {
    return BarChartGroupData(
      x: x,
      barRods: [
        BarChartRodData(
          toY: share,
          color: Colors.deepPurpleAccent,
          width: 6,
        ),
        BarChartRodData(
          toY: like,
          color: Colors.orange,
          width: 6,
        ),
        BarChartRodData(
          toY: coin,
          color: Colors.green,
          width: 6,
        ),
      ],
      showingTooltipIndicators: touchedGroupIndex == x ? [1] : [],
    );
  }

  @override
  void initState() {
    super.initState();
    PopularSeriesOneRequest.getPopularSeriesOneData().then((value) {
      setState(() {
        _list = value.list.sublist(0, 7);
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '每周必看59期',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '柱状图 (4)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 30.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildBarChart04(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildBarChart04() {
    return _list.isNotEmpty
        ? BarChart(BarChartData(
            alignment: BarChartAlignment.center,
            maxY: 1200000,
            minY: 0,
            barTouchData: BarTouchData(
              enabled: true,
              handleBuiltInTouches: false,
              touchTooltipData: BarTouchTooltipData(
                  tooltipBgColor: Colors.transparent,
                  tooltipMargin: 0,
                  getTooltipItem: (
                    BarChartGroupData group,
                    int groupIndex,
                    BarChartRodData rod,
                    int rodIndex,
                  ) {
                    return BarTooltipItem(
                      rod.toY.toString(),
                      TextStyle(
                          fontWeight: FontWeight.bold,
                          color: rod.color!,
                          fontSize: 10,
                          shadows: const [
                            Shadow(
                              color: Colors.black26,
                              blurRadius: 12,
                            )
                          ]),
                    );
                  }),
              touchCallback: (event, response) {
                if (event.isInterestedForInteractions &&
                    response != null &&
                    response.spot != null) {
                  setState(() {
                    touchedGroupIndex = response.spot!.touchedBarGroupIndex;
                  });
                } else {
                  setState(() {
                    touchedGroupIndex = -1;
                  });
                }
              },
            ),
            titlesData: FlTitlesData(
              show: true,
              bottomTitles: AxisTitles(
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 35,
                  getTitlesWidget: (value, meta) {
                    final index = value.toInt();
                    return SideTitleWidget(
                      axisSide: meta.axisSide,
                      child: _IconWidget(
                        imageNetwork: _list[index].pic,
                        isSelected: touchedGroupIndex == index,
                      ),
                    );
                  },
                ),
              ),
              leftTitles: AxisTitles(
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 40,
                  getTitlesWidget: (value, meta) {
                    String textValue = "";
                    switch (value.toInt()) {
                      case 500000:
                        textValue = "50万";
                        break;
                      case 1000000:
                        textValue = "100万";
                        break;
                      case 1200000:
                        textValue = "120万";
                        break;
                      default:
                        textValue = "";
                        break;
                    }
                    return Text(
                      textValue,
                      style: const TextStyle(
                        color: Color(0xFF606060),
                      ),
                      textAlign: TextAlign.left,
                    );
                  },
                ),
              ),
              topTitles: AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
              rightTitles: AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
            ),
            gridData: FlGridData(
              show: true,
              checkToShowHorizontalLine: (value) => value % 10 == 0,
              getDrawingHorizontalLine: (value) => FlLine(
                color: const Color(0xffe7e8ec),
                strokeWidth: 1,
              ),
              drawVerticalLine: false,
            ),
            borderData: FlBorderData(
              show: false,
            ),
            groupsSpace: 15,
            barGroups: getData()))
        : Container();
  }

  List<BarChartGroupData> getData() {
    List<BarChartGroupData> barGroups = [];
    int i = 0;
    for (var item in _list) {
      barGroups.add(generateBarGroup(
        i,
        item.stat["share"]!.toDouble(),
        item.stat["like"]!.toDouble(),
        item.stat["coin"]!.toDouble(),
      ));
      i++;
    }
    return barGroups;
  }
}

class _IconWidget extends ImplicitlyAnimatedWidget {
  final bool isSelected;
  final String imageNetwork;

  const _IconWidget({
    required this.imageNetwork,
    required this.isSelected,
  }) : super(duration: const Duration(milliseconds: 300));

  @override
  ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() =>
      _IconWidgetState();
}

class _IconWidgetState extends AnimatedWidgetBaseState<_IconWidget> {
  Tween<double>? _rotationTween;

  @override
  Widget build(BuildContext context) {
    final rotation = math.pi * 4 * _rotationTween!.evaluate(animation);
    final scale = 1 + _rotationTween!.evaluate(animation) * 0.5;
    return Transform(
      transform: Matrix4.rotationZ(rotation).scaled(scale, scale),
      origin: const Offset(14, 14),
      child: SizedBox(
        width: 25.px,
        height: 25.px,
        child: CircleAvatar(
          backgroundImage: NetworkImage(widget.imageNetwork),
        ),
      ),
    );
  }

  @override
  void forEachTween(TweenVisitor<dynamic> visitor) {
    _rotationTween = visitor(
      _rotationTween,
      widget.isSelected ? 1.0 : 0.0,
      (dynamic value) => Tween<double>(
        begin: value,
        end: widget.isSelected ? 1.0 : 0.0,
      ),
    ) as Tween<double>;
  }
}
